package com.qinglei.recoup.longconn.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.qinglei.recoup.longconn.constant.LongConnConstant;
import com.qinglei.recoup.longconn.utils.CRCUtils;
import com.qinglei.recoup.longconn.utils.CommonUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Message implements Serializable {
    /**
     * 协议头 2字节
     */
    private String header;
    /**
     * 项目码 1字节
     */
    private int projectCode;
    /**
     * 功能码 3字节
     */
    private String funcCode;
    /**
     * 指令号 2字节
     */
    private int nonce;
    /**
     * 加密方式 2字节
     */
    private int encMode;
    /**
     * SN 4字节
     */
    private String sn;
    /**
     * PN 7字节
     */
    private String pn;
    /**
     * 传输字节数，去除协议头，协议尾、校验位的长度 2字节
     */
    private int length;
    /**
     * 数据体 空则为0x00占位
     */
    private BodyT body;
    /**
     * 协议尾 2字节
     */
    private String tail;
    /**
     * CRC16校验码
     */
    private int crc16;
    /**
     * 获取数据时的时间戳 yyyy-MM-dd-HH-mm-ss-SSS
     */
    private String timestamp;
    /**
     * 毫秒时间戳
     */
    @JsonIgnore
    private long dataTime;

    public byte[] encode () {
        ByteBuf buffer = Unpooled.buffer();
        buffer.writeBytes(CommonUtils.hexStringToBytes(this.header));
        buffer.writeByte(this.projectCode);
        buffer.writeBytes(CommonUtils.hexStringToBytes(this.funcCode));
        buffer.writeShort(this.nonce);
        buffer.writeByte(this.encMode);
        buffer.writeBytes(CommonUtils.hexStringToBytes(this.sn));
        buffer.writeBytes(CommonUtils.hexStringToBytes(this.pn));
        byte[] body = this.body.encode();
        buffer.writeShort(body.length + LongConnConstant.FIXED_FIELD_LENGTH);
        buffer.writeBytes(body);
        buffer.writeBytes(CommonUtils.hexStringToBytes(this.tail));
        //校验数据
        byte[] crcBuf = new byte[buffer.readableBytes()];
        buffer.getBytes(0, crcBuf);
        int dataCrc = CRCUtils.getCRC16(crcBuf);
        buffer.writeShort(dataCrc);
        byte[] retBytes = new byte[buffer.readableBytes()];
        buffer.getBytes(0, retBytes);
        return retBytes;
    }
}
